package jblip.gui.components;

import java.awt.Color;
import java.lang.reflect.InvocationTargetException;

import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class WaitFrame extends JFrame {
  private static final long serialVersionUID = 1L;

  private static final String DEFAULT_TITLE = "Proszę czekać";

  private static final String DEFAULT_MSG = "Wykonuję zadanie";

  private static final long MSG_CHANGE_PERIOD = 500;

  private final JLabel wait_label;

  private final String msg;

  private class UpdateTask implements Runnable {
    private final Thread task_thread;

    private int info_dots;

    public UpdateTask(final Thread task) {
      this.task_thread = task;
    }

    @Override
    public void run() {
      while (task_thread.isAlive()) {
        synchronized (this) {
          try {
            wait(WaitFrame.MSG_CHANGE_PERIOD);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }

        info_dots = (info_dots + 1) % 4;
        final StringBuilder new_text = new StringBuilder(WaitFrame.this.msg);
        for (int i = 0; i < info_dots; i++) {
          new_text.append('.');
        }

        try {
          SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
              wait_label.setText(new_text.toString());
              wait_label.invalidate();
              wait_label.repaint();
            }
          });
        } catch (InterruptedException e) {
          e.printStackTrace();
        } catch (InvocationTargetException e) {
          e.printStackTrace();
        }
      }

      SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
          WaitFrame.this.dispose();
        }
      });
    }
  }

  public WaitFrame() {
    this(DEFAULT_TITLE, DEFAULT_MSG);
  }

  public WaitFrame(final String title, final String message) {
    super(title);
    this.msg = message;
    wait_label = new JLabel(message + "...");
    this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    this.add(initPane());
    this.pack();
    this.setLocationRelativeTo(null);
    this.setBackground(Color.WHITE);
    this.setResizable(false);
    this.setAlwaysOnTop(true);
    this.invalidate();
    this.repaint();
    this.setVisible(true);
  }

  private JPanel initPane() {
    JPanel pane = new JPanel();
    GroupLayout layout = new GroupLayout(pane);
    pane.setLayout(layout);

    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);

    layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(
        wait_label));
    layout.setVerticalGroup(layout.createSequentialGroup().addComponent(
        wait_label));

    pane.invalidate();
    pane.repaint();
    return pane;
  }

  public void runTask(final Thread task_thread) {
    Thread update_thread = new Thread(new UpdateTask(task_thread));
    task_thread.start();
    update_thread.start();
  }
}